#ifndef TASK_TIMESTAMP_H
#define TASK_TIMESTAMP_H

#include "Types.h"
#include "copyable.h"

class Timestamp : muduo::copyable {
public:
    Timestamp() : microSecondsSinceEpoch_(0) {
    }

    explicit Timestamp(int64_t microSecondsSinceEpochArg)
            : microSecondsSinceEpoch_(microSecondsSinceEpochArg) {
    }

    void swap(Timestamp &that) {
        std::swap(microSecondsSinceEpoch_, that.microSecondsSinceEpoch_);
    }

    /**
     * 转化为字符串输出
     * @return
     */
    std::string toString() const;

    /**
     * 转化为标准的格式输出
     * @param showMicroseconds 是否需要显示秒
     */
    std::string toFormattedString(bool showMicroseconds = true) const;

    bool valid() const { return microSecondsSinceEpoch_ > 0; }

    // for internal usage.
    int64_t microSecondsSinceEpoch() const { return microSecondsSinceEpoch_; }

    time_t secondsSinceEpoch() const {
        return static_cast<time_t>(microSecondsSinceEpoch_ / kMicroSecondsPerSecond);
    }

    /**
     * 获取当前时间
     */
    static Timestamp now();

    /**
     * 获取一个空的时间变量
     */
    static Timestamp invalid() {
        return Timestamp();
    }

    static Timestamp fromUnixTime(time_t t) {
        return fromUnixTime(t, 0);
    }

    static Timestamp fromUnixTime(time_t t, int microseconds) {
        return Timestamp(static_cast<int64_t>(t) * kMicroSecondsPerSecond + microseconds);
        // 从获取的时间变量转化为微秒值, 并加上对应的偏移
    }

    static const int kMicroSecondsPerSecond = 1000 * 1000;
    // 每秒多少微妙, 用这个记录以下

private:
    int64_t microSecondsSinceEpoch_;
    // 记录时间, 单位是微秒us
};

inline bool operator<(Timestamp lhs, Timestamp rhs) {
    return lhs.microSecondsSinceEpoch() < rhs.microSecondsSinceEpoch();
}

inline bool operator==(Timestamp lhs, Timestamp rhs) {
    return lhs.microSecondsSinceEpoch() == rhs.microSecondsSinceEpoch();
}

inline double timeDifference(Timestamp high, Timestamp low) {
    int64_t diff = high.microSecondsSinceEpoch() - low.microSecondsSinceEpoch();
    return static_cast<double>(diff) / Timestamp::kMicroSecondsPerSecond;
}

inline Timestamp addTime(Timestamp timestamp, double seconds) {
    int64_t delta = static_cast<int64_t>(seconds * Timestamp::kMicroSecondsPerSecond);
    return Timestamp(timestamp.microSecondsSinceEpoch() + delta);
    // 添加时间戳
}


#endif //TASK_TIMESTAMP_H
